﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;

namespace ShinyWizard.Tests
{
    [TestClass]
    public class PlainWizardNavigatorTests
    {
        #region GetPreviousStep

        [TestMethod]
        public void GetPreviousAvaliableStep()
        {
            // Arrange
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            var desirableStep = navigator.GetPreviousStep(steps, step2);
            // Assert
            Assert.IsTrue(ReferenceEquals(desirableStep, step1));
        }

        [TestMethod]
        public void ReturnNullWhenPreviousStepUnavaliable()
        {
            // Arrange
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            var desirableStep = navigator.GetPreviousStep(steps, step1);
            // Assert
            Assert.IsTrue(desirableStep == null);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void CannotGetPreviousStepForEmptyStepsCollection()
        {
            // Arrange
            var step = new WizardStep();
            var steps = new List<WizardStep>();
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.GetPreviousStep(steps, step);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void CannotGetPreviousStepForStepNotBelongStepsCollection()
        {
            // Arrange
            var independentStep = new WizardStep();
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.GetPreviousStep(steps, independentStep);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CannotGetPreviousStepForNullStepsCollection()
        {
            // Arrange
            var step = new WizardStep();
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.GetPreviousStep(null, step);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CannotGetPreviousStepForNullStep()
        {
            // Arrange
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.GetPreviousStep(steps, null);
            // Assert
        }

        #endregion

        #region GetNextStep

        [TestMethod]
        public void GetNextAvaliableStep()
        {
            // Arrange
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            var desirableStep = navigator.GetNextStep(steps, step1);
            // Assert
            Assert.IsTrue(ReferenceEquals(desirableStep, step2));
        }

        [TestMethod]
        public void ReturnNullWhenNextStepUnavaliable()
        {
            // Arrange
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            var desirableStep = navigator.GetNextStep(steps, step2);
            // Assert
            Assert.IsTrue(desirableStep == null);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void CannotGetNextStepForEmptyStepsCollection()
        {
            // Arrange
            var step = new WizardStep();
            var steps = new List<WizardStep>();
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.GetNextStep(steps, step);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void CannotGetNextStepForStepNotBelongStepsCollection()
        {
            // Arrange
            var independentStep = new WizardStep();
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.GetNextStep(steps, independentStep);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CannotGetNextStepForNullStepsCollection()
        {
            // Arrange
            var step = new WizardStep();
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.GetNextStep(null, step);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CannotGetNextStepForNullStep()
        {
            // Arrange
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.GetNextStep(steps, null);
            // Assert
        }

        #endregion

        #region IsPreviousStepAvaliable

        [TestMethod]
        public void CanDeterminePreviousStepAvaliable()
        {
            // Arrange
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            var avaliable = navigator.IsPreviousStepAvaliable(steps, step2);
            // Assert
            Assert.IsTrue(avaliable);
        }

        [TestMethod]
        public void CanDeterminePreviousStepUnavaliable()
        {
            // Arrange
            var step1 = new WizardStep();
            var steps = new List<WizardStep>{
                step1
            };
            var navigator = new PlainWizardNavigator();
            // Act
            var avaliable = navigator.IsPreviousStepAvaliable(steps, step1);
            // Assert
            Assert.IsFalse(avaliable);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void CannotDeterminePreviousStepAvaliableForEmptyStepsCollection()
        {
            // Arrange
            var step = new WizardStep();
            var steps = new List<WizardStep>();
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.IsPreviousStepAvaliable(steps, step);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void CannotDeterminePreviousStepAvaliableForStepNotBelongStepsCollection()
        {
            // Arrange
            var independentStep = new WizardStep();
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.IsPreviousStepAvaliable(steps, independentStep);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CannotDeterminePreviousStepAvaliableForNullStepsCollection()
        {
            // Arrange
            var step = new WizardStep();
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.IsPreviousStepAvaliable(null, step);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CannotDeterminePreviousStepAvaliableForNullStep()
        {
            // Arrange
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.IsPreviousStepAvaliable(steps, null);
            // Assert
        }

        #endregion

        #region IsNextStepAvaliable

        [TestMethod]
        public void CanDetermineNextStepAvaliable()
        {
            // Arrange
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            var avaliable = navigator.IsNextStepAvaliable(steps, step1);
            // Assert
            Assert.IsTrue(avaliable);
        }

        [TestMethod]
        public void CanDetermineNextStepUnavaliable()
        {
            // Arrange
            var step1 = new WizardStep();
            var steps = new List<WizardStep>{
                step1
            };
            var navigator = new PlainWizardNavigator();
            // Act
            var avaliable = navigator.IsNextStepAvaliable(steps, step1);
            // Assert
            Assert.IsFalse(avaliable);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void CannotDetermineNextStepAvaliableForEmptyStepsCollection()
        {
            // Arrange
            var step = new WizardStep();
            var steps = new List<WizardStep>();
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.IsNextStepAvaliable(steps, step);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void CannotDetermineNextStepAvaliableForStepNotBelongStepsCollection()
        {
            // Arrange
            var independentStep = new WizardStep();
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.IsNextStepAvaliable(steps, independentStep);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CannotDetermineNextStepAvaliableForNullStepsCollection()
        {
            // Arrange
            var step = new WizardStep();
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.IsNextStepAvaliable(null, step);
            // Assert
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CannotDetermineNextStepAvaliableForNullStep()
        {
            // Arrange
            var step1 = new WizardStep();
            var step2 = new WizardStep();
            var steps = new List<WizardStep>{
                step1,
                step2
            };
            var navigator = new PlainWizardNavigator();
            // Act
            navigator.IsNextStepAvaliable(steps, null);
            // Assert
        }

        #endregion
    }
}